package interpreter

import (
	"math"
	"parse/src/utils"
)

// 数字初始化
var Null = NewNumber(float64(0))
var False = NewNumber(float64(0))
var True = NewNumber(float64(1))
var MathPi = NewNumber(math.Pi)

// 数字
type Number struct {
	*BaseData
	Value interface{} // 为值，与Value区分，是
}

// 实例化number
func NewNumber(value interface{}) *Number {
	// 先实例化value
	temp := &Number{BaseData: NewBaseData()}
	// 初始化
	temp.InitNumber(value)
	return temp
}

// 初始化
func (v *Number) InitNumber(value interface{}) {
	// 父类初始化
	v.BaseData.InitBaseData()
	v.Value = value
}

// 加的函数覆写
func (v *Number) AddedTo(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(v.Value.(float64) + other.(*Number).Value.(float64))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 减的函数覆写
func (v *Number) SubbedTo(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(v.Value.(float64) - other.(*Number).Value.(float64))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 减的函数覆写
func (v *Number) SubbedBy(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(v.Value.(float64) - other.(*Number).Value.(float64))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 乘的函数覆写
func (v *Number) MultedTo(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(v.Value.(float64) * other.(*Number).Value.(float64))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 乘的函数覆写
func (v *Number) MultedBy(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(v.Value.(float64) * other.(*Number).Value.(float64))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 除的函数覆写
func (v *Number) DivedBy(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		// 分母为0，表示语法错误
		if other.(*Number).Value.(float64) == 0 {
			// 此处应该是报错
			return nil, NewRTError(other.(*Number).PosStart, other.(*Number).PosEnd, "除数，分母不能为0", v.Context)
		}
		t := NewNumber(v.Value.(float64) / other.(*Number).Value.(float64))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 求余数
func (v *Number) YuedBy(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		// 分母为0，表示语法错误
		if other.(*Number).Value.(float64) == 0 {
			// 此处应该是报错
			return nil, NewRTError(other.(*Number).PosStart, other.(*Number).PosEnd, "除数，分母不能为0", v.Context)
		}
		t := NewNumber(int64(v.Value.(float64)) % int64(other.(*Number).Value.(float64)))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 幂次方的函数覆写
func (v *Number) PowedBy(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(math.Pow(float64(v.Value.(float64)), float64(other.(*Number).Value.(float64))))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 比较的函数覆写
func (v *Number) GetComparisonEq(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(v.Value.(float64) == other.(*Number).Value.(float64))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 比较的函数覆写
func (v *Number) GetComparisonNe(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(v.Value.(float64) != other.(*Number).Value.(float64))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 比较的函数覆写
func (v *Number) GetComparisonLt(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(v.Value.(float64) < other.(Number).Value.(float64))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 比较的函数覆写
func (v *Number) GetComparisonGt(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(v.Value.(float64) > other.(*Number).Value.(float64))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 比较的函数覆写
func (v *Number) GetComparisonLte(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(v.Value.(float64) <= other.(Number).Value.(float64))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 比较的函数覆写
func (v *Number) GetComparisonGte(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(v.Value.(float64) >= other.(*Number).Value.(float64))
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 比较的函数覆写
func (v *Number) AndedBy(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(v.Value.(float64) > 0 && other.(*Number).Value.(float64) > 0)
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 比较的函数覆写
func (v *Number) OredBy(other interface{}) (interface{}, *RTError) {
	if utils.IsInstance(other, "Number") {
		t := NewNumber(v.Value.(float64) > 0 || other.(*Number).Value.(float64) > 0)
		t.SetContext(v.Context)
		return t, nil
	} else {
		return nil, v.IllegalOperation(other)
	}
}

// 比较的函数覆写
func (v *Number) NotedBy() (interface{}, *RTError) {
	t := NewNumber(v.Value.(float64) < 0)
	t.SetContext(v.Context)
	return t, nil
}

// 比较的函数覆写
func (v *Number) Copy() interface{} {
	copy_ := NewNumber(v.Value.(float64))
	copy_.SetPos(v.PosStart, v.PosEnd)
	copy_.SetContext(v.Context)
	return copy_
}

// 比较的函数覆写
func (v *Number) IsTrue() bool {
	b, err := v.Value.(bool)
	if !err { // 有错误
		return v.Value.(float64) > 0
	}
	return b
}
